﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows.Controls.Ribbon;
using SHomeWorkshop.LunarConcept.Controls;
using System.Windows;
using System.Xml;
using System.IO;

namespace SHomeWorkshop.LunarConcept.Commands
{
    /// <summary>
    /// 创建时间：2011年12月27日
    /// 创建者：  杨震宇
    /// 
    /// 主要用途：新建文档命令。
    ///           ——将每个命令都单独做成一个文件，是因为命令会很多，
    ///           都挤在MainWindow类的代码文件中会显得极为杂乱无章，且不利于修改。
    ///           
    ///           ——命令的全局唯一性也使得命令类没有必要以实例化的方式使用，静态类就可以了！
    ///           
    /// ★★说明：关于自定义命令
    ///           自定义命令的实现，关键在于：
    ///               ①向WPF系统注册一个RoutedUICommand实例；
    ///               ②新建一个CommandBinding实例，并将其Command属性值设置为注册的RoutedUICommand实例。
    ///               ③向主窗口的CommandBindings集合中添加CommandBinding实例。
    ///               ④将某些菜单或按钮的Command绑定到第一步注册的RoutedUICommand实例。
    ///                 ——当RoutedUICommand是静态类的静态属性的值时，绑定是很方便的。
    ///                     例如在Xaml代码中可以这样写：
    ///                         Command="{x:Static Member=cmds:NewDocumentCommand.RoutedUICmd}"
    ///                 ——点击菜单或按钮时，就会调用相关命令；
    ///                 ——菜单或按钮的可用状态将由CommandBinding来刷新，
    ///                     判断的依据是CanExecute事件的处理器方法。
    ///                     WPF认为需要刷新菜单状态时，就会寻找元素树上能找到的CommandBinds集合，
    ///                     然后再寻找此集合中有没有CommandBinding的Command与本菜单绑定的RoutedUICmd一致，
    ///                     如果找到，就引发CommandBinding的CanExecute事件，
    ///                     从而调用用户代码来判断菜单是否应该显示为可用。
    /// </summary>
    public static class NewDocumentCommand
    {
        #region 构造方法=====================================================================================================

        /// <summary>
        /// [静态][构造方法]
        /// 
        /// ——此方法会初始化并向WPF系统注册一个RoutedUICommand。
        /// </summary>
        static NewDocumentCommand()//类型构造器
        {
            routedUICmd = new RoutedUICommand(
                "NewDocumentCommand",
                "NewDocumentCommand",
                typeof(NewDocumentCommand),//创建RoutedUICommand对象
                null);//本程序考虑支持“命令模式”因此，这些命令完全没有必要直接支持快捷键。

            routedUICmd.InputGestures.Add(new KeyGesture(Key.N, ModifierKeys.Control, "Ctrl + N"));

            cmdBinding.Command = routedUICmd;
            cmdBinding.CanExecute += new CanExecuteRoutedEventHandler(cmdBinding_CanExecute);
            cmdBinding.Executed += new ExecutedRoutedEventHandler(cmdBinding_Executed);
        }

        #endregion

        #region 字段与属性===================================================================================================

        private static CommandBinding cmdBinding = new CommandBinding();
        /// <summary>
        /// 用在主窗口CommandBindings集合中的命令绑定。
        /// 
        /// 它的Command是RoutedUICommand。
        /// ——因此，RoutedUICommand是否可以运行将由CmdBinding的CanExecute事件决定。
        /// ——而且，RoutedUICommand的执行也是通过CmdBinding的Execute事件来进行的。
        /// </summary>
        public static CommandBinding CmdBinding
        {
            get { return cmdBinding; }
        }

        private static RoutedUICommand routedUICmd;
        /// <summary>
        /// [只读静态属性]表示在WPF系统中注册的一个RoutedUICommand。
        /// ——必须和CommandBinding配合才能使用。
        ///     CommandBinding要添加到主窗口的CommandBindings集合中；
        ///     RoutedUICommand则要向WPF系统注册。
        ///     
        /// ★说明：使用静态属性是因为这样在Xaml代码中比较便于绑定。
        /// </summary>
        public static RoutedUICommand RoutedUICmd
        {
            get { return routedUICmd; }
        }

        #endregion

        #region 方法=========================================================================================================

        /// <summary>
        /// 判断命令是否可以执行。
        /// ——由于可以直接调用Execute()方法，因此，即使被禁用，也不是不能执行相关功能！！！
        /// </summary>
        static void cmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;//新建文档，此命令总是有效。
        }

        /// <summary>
        /// 命令被触发时，会调用本事件处理器方法。
        /// ——本方法实际上是调用ExeCute()这个静态方法来实现特定功能。
        /// </summary>
        static void cmdBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            LunarMessage.Warning(Execute());
        }

        /// <summary>
        /// [公开静态方法]即使此命令处于禁用状态，也可以通过代码调用此方法来执行特定任务！！！
        /// 
        /// 当被绑定的命令被调用（触发）时，会引发cmdBinding_Executed事件。
        /// 在cmdBinding_Executed事件处理器方法中已添加了调用Execute()方法的代码。
        /// 
        /// ——因此，触发命令，就相当于调用此方法！！！
        /// </summary>
        /// <param name="templateFullFilePath">模板文件路径。</param>
        public static string Execute(string templateFullFilePath = null)
        {
            //System.Diagnostics.Process.Start(Globals.FullPathOfApp);

            if (Globals.MainWindow == null) return "　　未找到Globals.MainWindow。";
            EditorManager manager = Globals.MainWindow.EditorManager;
            if (manager == null) return "　　未找到页面管理器。";

            if (manager.IsModified)
            {
                //保存当前文件。
                MessageBoxResult result = MessageBox.Show("　　当前文档已被修改，要保存吗？",
                    Globals.AppName, MessageBoxButton.YesNoCancel, MessageBoxImage.Warning);
                try
                {
                    switch (result)
                    {
                        case MessageBoxResult.Yes:
                            {
                                string saveResult = Commands.SaveDocumentCommand.Execute();//保存后清除文档。

                                if (saveResult == Commands.SaveDocumentCommand.CancelSaveMessage)
                                {
                                    return string.Empty;
                                }

                                //清除EditorManager中所有内容、清除EditorManager的所有配置。
                                manager.CloseDocument();

                                //再新建个文档。
                                if (string.IsNullOrEmpty(templateFullFilePath) == false &&
                                    File.Exists(templateFullFilePath))
                                {
                                    return NewFromTemplate(templateFullFilePath);
                                }
                                else
                                {
                                    manager.XmlDocument.LoadXml(Properties.Resources.InitilizeXmlDocument);
                                    manager.Build();

                                    return string.Empty;
                                }
                            }
                        case MessageBoxResult.No:
                            {
                                //直接放弃当前内容。并新建文档。

                                manager.CloseDocument();

                                //再新建个文档。
                                if (string.IsNullOrEmpty(templateFullFilePath) == false &&
                                    File.Exists(templateFullFilePath))
                                {
                                    return NewFromTemplate(templateFullFilePath);
                                }
                                else
                                {
                                    manager.XmlDocument.LoadXml(Properties.Resources.InitilizeXmlDocument);
                                    manager.Build();
                                    return string.Empty;
                                }
                            }
                        default: return string.Empty;//取消新建文档操作。返回当前文档。
                    }
                }
                catch (Exception ex)
                {
                    return "　　未能新建文档。异常信息如下：\r\n" + ex.Message;
                }
            }
            else
            {
                //与“已修改但是放弃修改”等同。
                manager.CloseDocument();

                //再新建个文档。
                if (string.IsNullOrEmpty(templateFullFilePath) == false &&
                    File.Exists(templateFullFilePath))
                {
                    return NewFromTemplate(templateFullFilePath);
                }
                else
                {
                    manager.XmlDocument.LoadXml(Properties.Resources.InitilizeXmlDocument);
                    manager.Build();
                    return string.Empty;
                }
            }
        }

        private static string NewFromTemplate(string templateFullFilePath)
        {
            if (string.IsNullOrEmpty(templateFullFilePath))
                throw new FileNotFoundException();

            if (System.IO.File.Exists(templateFullFilePath) == false)
                throw new FileNotFoundException(templateFullFilePath);


            if (templateFullFilePath.EndsWith(Globals.ExtensionNameOfTemplate))
            {
                //XmlReader reader = null;
                //XmlReaderSettings settings = new XmlReaderSettings();
                //settings.ConformanceLevel = ConformanceLevel.Document;
                //settings.IgnoreWhitespace = true;
                //settings.IgnoreComments = true;
                //reader = XmlReader.Create(/*"file:///" +加这个会出错！！*/ templateFullFilePath, settings);

                bool start = false;
                StringBuilder sb = new StringBuilder();
                try
                {
                    using (StreamReader sr = File.OpenText(templateFullFilePath))
                    {
                        string s = "";
                        while ((s = sr.ReadLine()) != null)
                        {
                            if (start == false)
                            {
                                if (s.EndsWith(Globals.OutportImageSplitText))
                                {
                                    start = true;
                                }

                                continue;
                            }

                            sb.Append(s);
                        }

                        if (sb.Length <= 0)
                        {
                            throw new ArgumentException("　　指定的文件可能不是由本程序导出的模板文件！无法从中获取模板内容。");
                        }

                        Globals.MainWindow.EditorManager.XmlDocument.LoadXml(sb.ToString());
                        Globals.MainWindow.EditorManager.Build();
                        //Globals.MainWindow.EditorManager.FullPathOfDiskFile = string.Empty;//从模板文件新建与打开文档并不相同。
                        return string.Empty;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return null;
                }
            }
            else
            {
                throw new ArgumentException(
                    string.Format("传入的模板路径必须以{0}为后缀名结束。", Globals.ExtensionNameOfTemplate)
                    );
            }
        }

        #endregion

    }
}
